import "./App.css";
import { bitable, ITableMeta } from "@lark-base-open/js-sdk";
import {
  Button,
  Form,
  Toast,
  Table,
  Tooltip,
  Space,
  Modal,
  TextArea,
} from "@douyinfe/semi-ui";
import { BaseFormApi } from "@douyinfe/semi-foundation/lib/es/form/interface";
import { useState, useEffect, useRef, useCallback } from "react";

// 埋点类型映射关系
const EVENT_TYPE_MAPPING: Record<string, string> = {
  唤醒人工客服: "connectHumanAgen",
  IM商品点击: "IMProductClick",
  IM商品列表曝光: "IMProductOnshow",
  流量位点击: "flowClick",
  IM房间流量位曝光: "IMOnshow",
  IM房间流量位点击: "IMClick",
  商品详情页按钮点击: "productDetailClick",
  节点开始暂停: "nodePauseStart",
  商品详情页浏览: "productDetailPageView",
  商品点击: "productClick",
  商品列表曝光: "productOnshow",
  用户修改消息推送: "messagePushModify",
  用户是否开启消息推送: "messagePush",
  暂离切换在线: "employeeStatusChangeToOnline",
  暂离状态切换成功: "employeeStatusChangeToLeave",
  发起暂离审批: "employeeCreateLeaveApproval",
  还价列表按钮点击: "bargainListClick",
  一级节点完成: "firstNodeEnd",
  商品工单完结: "addProductTicketCompleted",
  商品工单被催审核: "productTicketUrgeReview",
  智能客服开启事件: "intelligentDelivery_varServiceOpen",
  智能客服关闭事件: "intelligentCustomerServiceClose",
  唤醒客服的点击: "customerServiceWakeUp",
  快捷操作点击: "speedyOperationClick",
  节点结束暂停: "nodePauseEnd",
  人工核验完成: "manualVerificationEnd",
  人工核验进入: "manualVerificationStart",
  二级节点实例完成: "secondaryNodeEnd",
  二级节点实例进入: "secondaryNodeStart",
  交付完结: "deliveryEnd",
  交付进入: "deliveryStart",
  卖家放款完成: "sellerPaymentReleaseSuccess",
  卖家商品被下单: "sellerProductCreateOrder",
  线下交易费用: "offlineTransactionFee",
  市场费用: "marketExpense",
  赔付追回: "claimRecovery",
  收支流水: "incomeAndExpenditure",
  放款成功: "paymentReleaseSuccess",
  优惠券领取成功: "couponReceived",
  "提交换绑（无效）": "applyForAccountTransfer",
  "换绑完结（无效）": "accountTransferComplete",
  "商品上架工单备注（无效）": "addProducTicketComment",
  流量位曝光: "flowOnshow",
  包赔订单退款成功: "refundCompensate",
  诚心卖履约服务退款申请成功: "faithService3RefundSuccess",
  诚心卖履约服务提交退款申请: "faithService3ApplyForRefund",
  诚心卖履约服务购买成功: "faithService3PaySuccess",
  立即支付生成订单: "paymentCreateOrder",
  提交退款申请: "applyForRefund",
  退款申请成功: "refundSuccess",
  包赔订单支付成功: "payCompensate",
  支付成功: "payOrderSuccess",
  生成包赔订单: "createCompensate",
  取消订单成功: "cancelOrder",
  生成订单: "createOrder",
  员工IM状态变更: "employeeChangeStatus",
  优惠券核销成功: "couponUsed",
  客诉工单完结: "complaintTicketCompleted",
  卖家说工单审核完结: "sellerTicketCompleted",
  商品上架工单跟进: "addProducTicketFollow",
  美工接单: "addProductArtFollow",
  卖家说工单提交: "sellerTicketSubmit",
  商品上架工单生成: "addProducTicketSubmit",
  授权成功: "authorizationSuccess",
  商品下架成功: "ProductTakeOffSuccess",
  商品上架成功: "ProductPutOnSuccess",
  卖家提交商品上架申请: "applyForPutOnShelf",
  注册成功: "registerSuccess",
  回收位咨询: "recycleGuidance",
  发布列表页去授权按钮点击: "releaseListClick",
  发布列表页去授权按钮曝光: "releaseListExpose",
  页面浏览: "$page",
  活动引流注册: "ployRegisterSuccess",
  活动引流登录: "ployLoginSuccess",
  工单收款成功: "ticketReceivePaymentCompleted",
  工单赔付完结: "payOutTicketCompleted",
  赔付工单审核完成: "payOutTicketAuthCompleted",
  发起工单赔付: "payOutTicketSubmit",
  客诉工单登记成功: "complaintTicketSubmit",
  售后工单处理完毕: "serviceTicketCompleted",
  售后工单登记成功: "serviceTicketSubmit",
  "员工应出勤时长（月）": "employeeRequiredAttendanceDuration_Month",
  "员工实际勤时长（月）": "employeeActualAttendanceDuration_Month",
  卖家签署合同完成: "sellerContractSigned",
  买家签署合同完成: "buyerContractSigned",
  曝光券购买成功: "exposureServicePaySuccess",
  诚心卖购买成功: "faithServicePaySuccess",
  商品详情页关闭: "productDetailPageClose",
  用户留资成功: "infoLoadingSuccess",
  用户放款账户提交成功: "accountSubmit",
  用户注销成功: "signOutSuccess",
  实名认证成功: "identityVerification",
  筛选请求发起: "filterProductApply",
  搜索请求发起: "searchProductApply",
  资源位曝光: "adOnshow",
  登录成功: "loginSuccess",
  资源位点击: "adClick",
  AB实验入组: "$exp_hit",
  "智能运营-渠道触达": "$ma_channel_touch",
  深度链接唤醒事件: "$ads_reengage",
  小程序分享到朋友圈: "$mp_share_timeline",
  小程序添加收藏: "$mp_add_favorites",
  小程序分享事件: "$mp_on_share",
  广告激活: "$ads_activation",
  广告点击: "$ads_click",
  广告曝光: "$ads_imp",
  元素修改: "$view_change",
  元素点击: "$view_click",
  访问: "$visit",
  任意事件: "$anyevent",
  访问跳出: "$bounce",
  访问退出: "$exit",
};

/**
 * [GrowingIO Debug]: {
  eventType: CUSTOM,
  eventName: adOnshow,
  appVersion: 1.0.0,
  dataSourceId: 879bd19e0ba5e497,
  deviceId: 74e8aff6-9f05-42a3-9427-e015cc9c3e18,
  domain: h5-test.pxb7.com,
  language: zh-CN,
  path: /,
  platform: web,
  referralPage: https://h5-test.pxb7.com/pages-my/BuyerOrder/index,
  screenHeight: 667,
  screenWidth: 375,
  sdkVersion: 4.2.4,
  sessionId: 32f0c146-0452-41f7-8a1a-c00078097c0b,
  timestamp: 1760580712857,
  timezoneOffset: -480,
  title: 首页,
  userId: 400154199,
  attributes: {
    pageType_var: 首页,
    pageName_var: 首页,
    productType_var: -,
    gameID_var: -,
    rcToken: -,
    ployCode_var: -,
    referrerPageName_var: 我买到的,
    pitName_var: 曝光,
    pitPosition_var: 3,
    moduleName_var: 顶部banner,
    adId_var: 167920936624155,
    adName_var: 首页202508
  },
  eventSequenceId: 19971
}
eruda.js:23 
 */

// 参数字段映射关系
const PARAM_FIELD_MAPPING: Record<string, string> = {
  页面名称: "pageName_var",
  页面类型: "pageType_var",
  模块名称moduleName_var: "moduleName_var",
  坑位名称pitName_var: "pitName_var",
  坑位位置pitPosition_var: "pitPosition_var",
};

interface RecordData {
  recordId: string;
  _index: number; // 添加索引字段保持顺序
  [key: string]: any;
}

export default function App() {
  const [tableMetaList, setTableMetaList] = useState<ITableMeta[]>();
  const [records, setRecords] = useState<RecordData[]>([]);
  const [loading, setLoading] = useState(false);
  const [exposureModalVisible, setExposureModalVisible] = useState(false);
  const [currentExposureRecord, setCurrentExposureRecord] =
    useState<RecordData | null>(null);
  const formApi = useRef<BaseFormApi>();

  useEffect(() => {
    Promise.all([
      bitable.base.getTableMetaList(),
      bitable.base.getSelection(),
    ]).then(([metaList, selection]) => {
      setTableMetaList(metaList);
      formApi.current?.setValues({ table: selection.tableId });
    });
  }, []);

  // 读取表格数据
  const readTableData = useCallback(
    async ({ table: tableId }: { table: string }) => {
      if (!tableId) {
        Toast.warning("请先选择表格");
        return;
      }

      setLoading(true);
      try {
        const table = await bitable.base.getTableById(tableId);
        const fieldMetaList = await table.getFieldMetaList();

        // 获取视图列表并使用第一个视图的有序记录列表
        const viewMetaList = await table.getViewMetaList();
        const view = await table.getViewById(viewMetaList[0].id);
        const recordIdList = await view.getVisibleRecordIdList();

        const recordsData: RecordData[] = [];

        for (let i = 0; i < recordIdList.length; i++) {
          const recordId = recordIdList[i];
          if (!recordId) continue;
          const recordValues = await table.getRecordById(recordId);
          const recordData: RecordData = {
            recordId,
            _index: i, // 保存原始索引
          };

          for (const field of fieldMetaList) {
            const cellValue = recordValues.fields[field.id];
            let displayValue = "";

            if (cellValue !== null && cellValue !== undefined) {
              if (Array.isArray(cellValue)) {
                displayValue = cellValue
                  .map((item) => {
                    if (
                      typeof item === "object" &&
                      item !== null &&
                      "text" in item
                    ) {
                      return (item as any).text;
                    }
                    return item;
                  })
                  .join(", ");
              } else if (
                typeof cellValue === "object" &&
                cellValue !== null &&
                "text" in cellValue
              ) {
                displayValue = (cellValue as any).text;
              } else {
                displayValue = String(cellValue);
              }
            }

            recordData[field.name] = displayValue || "-";
          }

          recordsData.push(recordData);
        }

        setRecords(recordsData);
        Toast.success(`成功读取 ${recordsData.length} 条记录`);
      } catch (error) {
        console.error("读取数据失败:", error);
        Toast.error("读取数据失败");
      } finally {
        setLoading(false);
      }
    },
    []
  );

  // 生成单条记录的代码
  const generateSingleCode = useCallback((record: RecordData) => {
    const eventTypeRaw = record["埋点类型"] || "";

    // 忽略"页面浏览"类型
    if (eventTypeRaw === "页面浏览") {
      return "";
    }

    // 获取埋点类型的映射值
    const eventType =
      EVENT_TYPE_MAPPING[eventTypeRaw] || eventTypeRaw || "flowClick";

    const params: Record<string, string> = {};

    // 根据字段映射生成参数
    Object.entries(PARAM_FIELD_MAPPING).forEach(([fieldName, varName]) => {
      params[varName] = record[fieldName] || "-";
    });

    // 检查是否有其他 _var 结尾的字段
    Object.keys(record).forEach((fieldName) => {
      if (fieldName.endsWith("_var") && !PARAM_FIELD_MAPPING[fieldName]) {
        // 提取 _var 部分作为参数名，例如 "中文名称aaa_var" -> "aaa_var"
        const match = fieldName.match(/([a-zA-Z0-9_]+_var)$/);
        const varName = match ? match[1] : fieldName;
        params[varName] = record[fieldName] || "-";
      }
    });

    // 生成参数字符串
    const paramsStr = Object.entries(params)
      .map(([key, value]) => `${key}: '${value}'`)
      .join(",\n  ");

    const code = paramsStr
      ? `gdpInstance.track('${eventType}', {\n  ${paramsStr}\n})`
      : `gdpInstance.track('${eventType}')`;

    return code;
  }, []);

  // 生成曝光埋点代码 - HTML部分
  const generateExposureHtmlCode = useCallback((record: RecordData) => {
    const eventTypeRaw = record["埋点类型"] || "";
    const eventType =
      EVENT_TYPE_MAPPING[eventTypeRaw] || eventTypeRaw || "flowOnshow";

    return `data-gio-imp-type="once"
data-gio-imp-track="${eventType}"
:data-gio-imp-attrs="computeDataAttrString()"`;
  }, []);

  // 生成曝光埋点代码 - JS部分
  const generateExposureJsCode = useCallback((record: RecordData) => {
    const params: Record<string, string> = {};

    // 根据字段映射生成参数
    Object.entries(PARAM_FIELD_MAPPING).forEach(([fieldName, varName]) => {
      params[varName] = record[fieldName] || "-";
    });

    // 检查是否有其他 _var 结尾的字段
    Object.keys(record).forEach((fieldName) => {
      if (fieldName.endsWith("_var") && !PARAM_FIELD_MAPPING[fieldName]) {
        // 提取 _var 部分作为参数名，例如 "中文名称aaa_var" -> "aaa_var"
        const match = fieldName.match(/([a-zA-Z0-9_]+_var)$/);
        const varName = match ? match[1] : fieldName;
        params[varName] = record[fieldName] || "-";
      }
    });

    // 生成参数对象字符串
    const paramsObjStr = Object.entries(params)
      .map(([key, value]) => `    ${key}: '${value}'`)
      .join(",\n");

    return `const computeDataAttrString = computed(() => {
  return (item) => {
    return JSON.stringify({
${paramsObjStr}
    });
  };
});`;
  }, []);

  // 打开曝光弹窗
  const openExposureModal = useCallback((record: RecordData) => {
    setCurrentExposureRecord(record);
    setExposureModalVisible(true);
  }, []);

  // 关闭曝光弹窗
  const closeExposureModal = useCallback(() => {
    setExposureModalVisible(false);
    setCurrentExposureRecord(null);
  }, []);

  // 复制HTML代码
  const copyHtmlCode = useCallback(() => {
    if (!currentExposureRecord) return;

    const code = generateExposureHtmlCode(currentExposureRecord);
    navigator.clipboard
      .writeText(code)
      .then(() => {
        Toast.success("HTML代码已复制到剪贴板");
      })
      .catch(() => {
        Toast.error("复制失败");
      });
  }, [currentExposureRecord, generateExposureHtmlCode]);

  // 复制JS代码
  const copyJsCode = useCallback(() => {
    if (!currentExposureRecord) return;

    const code = generateExposureJsCode(currentExposureRecord);
    navigator.clipboard
      .writeText(code)
      .then(() => {
        Toast.success("JS代码已复制到剪贴板");
      })
      .catch(() => {
        Toast.error("复制失败");
      });
  }, [currentExposureRecord, generateExposureJsCode]);

  // 复制单条代码
  const copySingleCode = useCallback(
    (record: RecordData) => {
      const code = generateSingleCode(record);
      if (!code) {
        Toast.warning("该记录无法生成代码");
        return;
      }

      navigator.clipboard
        .writeText(code)
        .then(() => {
          Toast.success("代码已复制到剪贴板");
        })
        .catch(() => {
          Toast.error("复制失败");
        });
    },
    [generateSingleCode]
  );

  // 表格列定义
  const columns = [
    {
      title: "序号",
      dataIndex: "_index",
      width: 80,
      render: (_: any, record: RecordData) => record._index + 1,
    },
    {
      title: "触发时机",
      dataIndex: "触发时机",
      width: 200,
    },
    {
      title: "页面名称",
      dataIndex: "页面名称",
      width: 150,
    },
    {
      title: "模块名称",
      dataIndex: "模块名称moduleName_var",
      width: 150,
    },
    {
      title: "操作",
      dataIndex: "action",
      width: 150,
      fixed: "right" as const,
      render: (_: any, record: RecordData) => {
        const code = generateSingleCode(record);
        const eventTypeRaw = record["埋点类型"] || "";
        const isExposure = eventTypeRaw.includes("曝光");

        if (!code && !isExposure) return null;

        return (
          <Space>
            {code && (
              <Tooltip
                content={
                  <pre
                    style={{
                      margin: 0,
                      padding: "8px",
                      fontSize: "12px",
                      maxWidth: "400px",
                      whiteSpace: "pre-wrap",
                      wordBreak: "break-word",
                    }}
                  >
                    {code}
                  </pre>
                }
                position="left"
              >
                <Button size="small" onClick={() => copySingleCode(record)}>
                  复制
                </Button>
              </Tooltip>
            )}
            {isExposure && (
              <Button
                size="small"
                type="secondary"
                onClick={() => openExposureModal(record)}
              >
                曝光
              </Button>
            )}
          </Space>
        );
      },
    },
  ];

  return (
    <main className="main" style={{ padding: "20px" }}>
      <h2>埋点代码生成器</h2>

      <Form
        labelPosition="top"
        onSubmit={readTableData}
        getFormApi={(baseFormApi: BaseFormApi) =>
          (formApi.current = baseFormApi)
        }
      >
        <Form.Select
          field="table"
          label="选择表格"
          placeholder="请选择表格"
          style={{ width: "100%" }}
        >
          {Array.isArray(tableMetaList) &&
            tableMetaList.map(({ name, id }) => {
              return (
                <Form.Select.Option key={id} value={id}>
                  {name}
                </Form.Select.Option>
              );
            })}
        </Form.Select>

        <Button theme="solid" htmlType="submit" loading={loading}>
          读取表格数据
        </Button>
      </Form>

      {records.length > 0 && (
        <div style={{ marginTop: "20px" }}>
          <h3>读取到 {records.length} 条记录</h3>
          <Table
            columns={columns}
            dataSource={records}
            pagination={{
              pageSize: 10,
              showSizeChanger: true,
              pageSizeOpts: [10, 20, 50, 100],
            }}
            rowKey="recordId"
            style={{ marginTop: "10px" }}
          />
        </div>
      )}

      <Modal
        title="曝光埋点代码"
        visible={exposureModalVisible}
        onCancel={closeExposureModal}
        footer={null}
        width={700}
      >
        {currentExposureRecord && (
          <div>
            <div style={{ marginBottom: "20px" }}>
              <div
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                  marginBottom: "8px",
                }}
              >
                <h4 style={{ margin: 0 }}>HTML 代码</h4>
                <Button size="small" onClick={copyHtmlCode}>
                  复制
                </Button>
              </div>
              <TextArea
                value={generateExposureHtmlCode(currentExposureRecord)}
                autosize={{ minRows: 3, maxRows: 6 }}
                style={{ fontFamily: "monospace", fontSize: "12px" }}
                readOnly
              />
            </div>

            <div>
              <div
                style={{
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                  marginBottom: "8px",
                }}
              >
                <h4 style={{ margin: 0 }}>JS 代码</h4>
                <Button size="small" onClick={copyJsCode}>
                  复制
                </Button>
              </div>
              <TextArea
                value={generateExposureJsCode(currentExposureRecord)}
                autosize={{ minRows: 8, maxRows: 15 }}
                style={{ fontFamily: "monospace", fontSize: "12px" }}
                readOnly
              />
            </div>
          </div>
        )}
      </Modal>
    </main>
  );
}
